package com.example.db.utils;

import android.util.Base64;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by kkmike999 on 16/1/14.
 */
public class KryoUtil {
    private static Kryo kryo = new Kryo();

    /**
     * 对象序列化成byte[]
     *
     * @param object
     *
     * @return
     */
    public static byte[] toBytes(Object object) {
        kryo.register(object.getClass());

        ByteArrayOutputStream bout   = new ByteArrayOutputStream();
        Output                output = new Output(bout);

        try {
            kryo.writeObject(output, object);
        } catch (Exception e) {
            e.printStackTrace();
        }

        output.close();

        return bout.toByteArray();
    }

    /**
     * 对象序列化成String
     *
     * @param object
     *
     * @return
     */
    public static String toString(Object object) {
        byte[] bytes  = toBytes(object);
        String string = Base64.encodeToString(bytes, Base64.DEFAULT);

        return string;
    }

    /**
     * string反序列化为对象
     *
     * @param string
     * @param clazz
     * @param <T>
     *
     * @return
     */
    public static <T> T parseString(String string, Class<T> clazz) {
        return parseBytes(Base64.decode(string, Base64.DEFAULT), clazz);
    }

    /**
     * string反序列化为对象
     *
     * @param string
     * @param clazz
     * @param <T>
     *
     * @return
     */
    public static <T> List<T> parseListString(String string, Class<T> clazz) {
        return parseListBytes(Base64.decode(string, Base64.DEFAULT), clazz);
    }


    public static <T> T parseBytes(byte[] bytes, Class<T> clazz) {
        kryo.register(clazz);

        Input input = new Input(bytes);

        T t = null;
        try {
            t = kryo.readObject(input, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            input.close();
        }

        return t;
    }

    public static <T> List<T> parseListBytes(byte[] bytes, Class<T> clazz) {
        try {
            kryo.register(clazz.getClass());

            List<T> list = new ArrayList<>();

            Input input = new Input(bytes);

            try {
                list = (List<T>) kryo.readObject(input, list.getClass());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                input.close();
            }

            if (list instanceof List)
                return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ArrayList<>();
    }

}
